package com.pvdnc.riru.appinjector;

import android.app.Application;
import android.util.Log;

import com.pvdnc.riru.common.ApplicationObserver;
import com.pvdnc.riru.common.ApplicationObserverManager;
import com.pvdnc.riru.common.ServiceObserverManager;

import java.lang.reflect.Method;

import andhook.lib.xposed.XC_MethodHook;
import andhook.lib.xposed.XposedBridge;

public class HookEnvManager {
    private static final String TAG=HookEnvManager.class.getSimpleName();

    public static final HookEnvManager INSTANCE=new HookEnvManager();

    private HookEnvManager(){

    }

    public void init() {
        AppClassLoader.INSTANCE.hookAll();//接管app类加载器
        try {
            ServiceObserverManager.INSTANCE.addObserver("package", HookPMS.INSTANCE);
            hookSetProperty();
        } catch (Exception e) {
            e.printStackTrace();
        }
        ApplicationObserverManager.INSTANCE.addObserver(new ApplicationObserver() {
            @Override
            public void beforeApplicationOnCreate(Application app) {
                //注入
                try {
                    if (LoadablePackages.fromPMS().isHookable()) {
                        AppClassLoader.INSTANCE.injectRiruClasses();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                AppModuleLoader.INSTANCE.loadModules(app);
            }
        });
    }

    public static final String PROPERTY_ENV_LOADED="riru.property_env_loaded";

    private void hookSetProperty() throws Exception {
        Method method=System.class.getDeclaredMethod("setProperty", String.class, String.class);
        XposedBridge.hookMethod(method,new XC_MethodHook(){
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                try{
                    String name= (String) param.args[0];
                    if(!PROPERTY_ENV_LOADED.equals(name))
                        return;
                    Log.d(TAG,"after change Riru env loaded property");
                    String value= (String) param.args[1];
                    if(!Boolean.parseBoolean(value)){
                        Log.d(TAG,"attempt to remove riru classes");
                        AppClassLoader.INSTANCE.removeRiruClasses();
                    }else{
                        Log.d(TAG,"attempt to inject riru classes");
                        AppClassLoader.INSTANCE.injectRiruClasses();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
        Log.d(TAG,"finish hooking setProperty");
    }


}
